<template>
  <el-dialog
    :modal-append-to-body="false"
    key="newTemplateDialog"
    :top="step === 1 ? '2vh' : '15vh'"
    ref="dialog"
    :title="title"
    v-bind="$attrs"
    :width="dialogWidth"
    class="select-template-dialog"
    :class="{ 'select-file-format': step === 2 }"
    v-on="$listeners"
    @closed="resetData"
    @open="open"
  >
    <!-- 第一步 -->
    <el-row v-if="step === 1" type="flex">
      <el-col :span="4" class="sidebar">
        <!-- <div class="text-center font-bold py-5 title">Template Mode</div> -->
        <ul class="menu">
          <li
            class="menu-item"
            :class="{ active: active === 'simple' }"
            @click="changeMode(MODE.SIMPLE, 'simple')"
          >
            <img :src="require('@/assets/images/flyparameter/simple2.jpg')" />
            <span>{{ $t("flyparam.simple") }}</span>
          </li>
          <li
            class="menu-item"
            :class="{ active: active === 'design' }"
            @click="changeMode(MODE.DESIGN, 'design')"
          >
            <img :src="require('@/assets/images/flyparameter/complicated2.jpg')" />{{
              $t("flyparam.design")
            }}
          </li>
        </ul>
      </el-col>
      <el-col :span="14" class="select-template">
        <div style="height: calc(100vh - 90px); overflow: auto">
          <div class="import-template">
            <p class="title">{{ $t("flyparam.add_template") }}</p>
            <el-row :gutter="20">
              <el-col :span="8">
                <div class="inline-block mb-2 w-full">
                  <div
                    :class="[
                      'template-box',
                      'blank',
                      { selected: selectedTemplateIndex === 'blank' },
                    ]"
                    @click.stop="(e) => (selectedTemplateIndex = 'blank')"
                    @dblclick="() => nextStep('blank')"
                  >
                    <div style="height: calc(100% - 44px); position: relative">
                      <span class="item-new">
                        <i class="el-icon-plus"></i>
                      </span>
                    </div>
                    <div class="template-box__bottom">
                      <p class="template-name">
                        {{ $t("flyparam.blank_template") }}
                      </p>
                    </div>
                  </div>
                </div>
              </el-col>
              <el-col :span="16">
                <div class="text-center">
                  <el-upload
                    drag
                    action
                    multiple
                    :auto-upload="false"
                    :show-file-list="false"
                    :limit="1"
                    :on-change="handleFileChange"
                    ref="upload"
                  >
                    <i class="el-icon-upload"></i>
                    <div class="el-upload__text">
                      {{ $t("flyparam.template_upload_tip1") }}
                      <br />{{ $t("flyparam.template_upload_tip2") }}. <br />{{
                        $t("flyparam.template_upload_tip3", { type: ".zip" })
                      }}
                    </div>
                  </el-upload>
                </div>
              </el-col>
            </el-row>
          </div>
          <div class="templates-container" v-loading="loading">
            <p class="title">{{ $t("flyparam.template_choose_list") }}</p>
            <el-row :gutter="20">
              <el-col :span="8" v-for="(item, index) in templates" :key="index">
                <div class="inline-block mb-2 w-full">
                  <div
                    :class="[
                      'template-box',
                      {
                        blank: item.keyId === 0,
                        preference: item.keyId === 0,
                        selected: selectedTemplateIndex === index,
                      },
                    ]"
                    @click.stop="(e) => (selectedTemplateIndex = index)"
                    @dblclick="() => handleTemplateDoubleClick(index)"
                  >
                    <div class="image-tag" v-if="item.keyId === 0">
                      {{ $t("flyparam.system_preference") }}
                    </div>
                    <img
                      class="template-image"
                      v-if="active === 'simple'"
                      :src="require('@/assets/images/flyparameter/simple.jpg')"
                      alt
                    />

                    <img
                      class="template-image"
                      v-else-if="active === 'design'"
                      :src="require('@/assets/images/flyparameter/complicated.jpg')"
                      alt
                    />
                    <div class="template-box__bottom">
                      <p class="template-name" v-ellipsis>{{ item.appName }}</p>
                      <span class="template-actions" v-if="item.keyId != 0">
                        <span
                          class="item-delete"
                          @click.stop="(e) => deleteTemplate(item)"
                        >
                          <i class="el-icon-delete"></i>
                        </span>
                        <span
                          class="item-edit ml-4"
                          @click.stop="(e) => editTemplate(item.id)"
                        >
                          <i class="el-icon-edit"></i>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </el-col>
              <el-col :span="8">
                <div class="inline-block mb-2 w-full">
                  <div class="template-box new" @click="() => (visible = true)">
                    <span class="item-new">
                      <i class="el-icon-plus"></i>
                    </span>
                  </div>

                  <p class="text-center">
                    {{ $t("flyparam.add_common_template") }}
                  </p>
                </div>
              </el-col>
            </el-row>
          </div>
          <div class="select-template__footer">
            <el-button @click="cancel" size="small">{{ $t("common.cancel") }}</el-button>
            <el-button
              size="small"
              type="primary"
              :disabled="selectedTemplateIndex === -1"
              @click="nextStep"
              >{{ $t("common.confirm") }}</el-button
            >
          </div>
        </div>
      </el-col>
      <el-col :span="6" class="introduction" v-if="this.active === 'simple'">
        <div class="leading-loose">
          <h2 class="text-xl">{{ $t("flyparam.introduction") }}</h2>
          <!--          简单模式模板更适合于简单的场景，参数配置只是一个简单的键值形式，很容易理解。-->
          <p v-html="$t('flyparam.simple_intro_text')"></p>

          <h2 class="mt-2 text-xl">{{ $t("flyparam.scene_desc") }}</h2>
          <!--          不考虑某些通用参数的管理，只想通过平台针对终端做简单的key/value 形式的参数配置的管理。-->
          <p v-html="$t('flyparam.simple_scene_text')"></p>

          <!--<h2 class="mt-2 text-xl">{{$t('flyparam.guide')}}</h2>
          <video width="320" height="240" controls>
            <source :src="require('@/assets/videos/FlyKey1.24b3504.mp4')" type="video/mp4" />
          </video>-->
        </div>
      </el-col>
      <el-col :span="6" class="introduction" v-else>
        <div class="leading-loose">
          <h2 class="text-xl">{{ $t("flyparam.introduction") }}</h2>
          <!--          设计模式模板涵盖我们设计的全部特性，我们会更推荐您使用它。参数配置支持多层级嵌套的键值形式，更贴近实际场景-->
          <p v-html="$t('flyparam.design_intro_text')"></p>

          <h2 class="mt-2 text-xl">{{ $t("flyparam.scene_desc") }}</h2>
          <p v-html="$t('flyparam.design_scene_desc')"></p>
          <ul style="list-style: disc">
            <li v-html="$t('flyparam.design_scene_desc_2')"></li>
            <li v-html="$t('flyparam.design_scene_desc_3')"></li>
            <li v-html="$t('flyparam.design_scene_desc_4')"></li>
          </ul>
        </div>
      </el-col>
    </el-row>
    <!--  -->
    <!-- 第二步 -->
    <div v-if="step === 2" class="choose-format">
      <div class="mb-5">
        <span class="mr-3">{{ $t("flyparam.cfg_format") }}:</span>
        <el-radio-group v-model="format">
          <el-radio :label="1">JSON</el-radio>
          <el-radio :label="2">ASN.1</el-radio>
          <el-radio :label="3">XML</el-radio>
        </el-radio-group>
      </div>

      <p>
        <span class>{{ $t("flyparam.tip") }}:</span>
        <span v-html="$t('flyparam.cfg_format_tip')"> </span>
      </p>
    </div>
    <template #footer>
      <span v-if="step === 2">
        <el-button size="small" @click="cancel">{{ $t("common.cancel") }}</el-button>
        <el-button
          size="small"
          type="primary"
          :loading="loading"
          @click="handleConfirm"
          >{{ $t("common.confirm") }}</el-button
        >
      </span></template
    >
    <!-- 新建模板 -->
    <el-dialog
      append-to-body
      :visible="visible"
      :title="$t('flyparam.add_template')"
      style="margin-top: 25vh"
      width="600px"
      @close="newTemplateClose"
    >
      <el-form ref="form" :model="form" :rules="rules" @submit.native.prevent>
        <el-form-item :label="$t('flyparam.template_name')" prop="appName">
          <el-input
            v-model="form.appName"
            @change="() => (form.appName = form.appName.trim())"
            size="small"
            :maxlength="128"
          />
        </el-form-item>
        <el-form-item :label="$t('common.description')" prop="description">
          <el-input v-model="form.description" size="small" :maxlength="255" />
        </el-form-item> </el-form
      ><template #footer>
        <div>
          <el-button size="small" @click="newTemplateClose">{{
            $t("common.cancel")
          }}</el-button>
          <el-button
            type="primary"
            size="small"
            :loading="loading"
            @click="newTemplate"
            >{{ $t("common.confirm") }}</el-button
          >
        </div></template
      >
    </el-dialog>
    <!-- 上传模板加载中 -->
    <loading-dialog
      :title="loadingDialogTitle"
      @cancel="() => $refs.upload.clearFiles()"
      :task-uuid="taskUuid"
      :estimate-time="estimateTime"
      :app-package-name="appPackageName"
      v-model="loadingDialogVisible"
      :file-name="fileName"
    ></loading-dialog>
  </el-dialog>
</template>

<script>
import {
  createBlankTemplate,
  createTemplateByTemplateId,
  getSpecificModeTemplateList,
  deleteTemplateByTemplateId,
  addCommonParamTemplate,
} from "@/api/parameter";
import request from "@/utils/request";
import LoadingDialog from "./loading-dialog.vue";

function validateTemplateName(rule, value, callback) {
  if (value) {
    if (/^\s+$/.test(value)) {
      // 纯空格报错
      callback(new Error(this.$t("flyparam.invalid_input")));
    }
  }
  callback();
}
const MODE = {
  DESIGN: 1,
  SIMPLE: 2,
};

export default {
  props: {
    info: {
      type: Object,
    },
    source: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      keepAlive: false,
      selected: 0, // 选中的模版索引
      selectedTemplateIndex: "blank",
      percentState: 0,
      progressStatus: null,
      mode: MODE.SIMPLE,
      active: "simple", // 当前菜单
      title: this.$t("flyparam.select_template"),
      step: 1, // 步骤，共两步，第一步选模版，第二部选cfg文件格式
      dialogWidth: "70%",
      format: 1,
      creUerName: "",
      id: 1000,
      templates: [],
      isBlankTemplate: false,
      commonTemplateId: "",
      choosedTemplate: null,
      visible: false,
      showUpload: true,
      formData: null,
      form: {
        appName: "",
        fileType: 1,
        description: "",
      },
      rules: {
        appName: [
          {
            required: true,
            message: this.$t("common.please_input"),
            trigger: "blur",
          },
          {
            validator: validateTemplateName.bind(this),
          },
        ],
      },
      newTemplateName: "",
      MODE: Object.freeze(MODE),
      loading: false,
      loadingDialogVisible: false,
      continueLoading: false,
      fileName: "",
      progress: 0,
      taskUuid: "",
      appPackageName: "",
      loadingDialogTitle: "",
    };
  },
  components: {
    LoadingDialog,
  },
  methods: {
    nextStep() {
      this.step++;
      this.dialogWidth = "50%";
      this.title = this.$t("flyparam.select_cfg_format");
      if (this.selectedTemplateIndex === "blank") {
        this.isBlankTemplate = true;
      } else {
        const item = this.templates[this.selectedTemplateIndex];
        this.commonTemplateId = item.id;
      }
    },
    handleTemplateDoubleClick(index) {
      this.selectedTemplateIndex = index;
      this.nextStep();
    },
    cancel() {
      this.newTemplateClose();
      this.$emit("update:model-value", false);
    },
    // 重置数据到初始值
    resetData() {
      if (!this.keepAlive) {
        this.step = 1;
        this.dialogWidth = "70%";
        this.title = this.$t("flyparam.select_template");
        this.mode = MODE.SIMPLE;
        this.active = "simple";
        this.$store.commit("app/REMOVE_KEEP_ALIVE_LIST", "FlyParameter");
      }

      this.newTemplateClose();
    },
    handleConfirm() {
      this.loading = true;
      const data = {
        mode: this.mode,
        appName: this.$store.state.parameter.newTemplate.appName,
        appPackageName: this.$store.state.parameter.newTemplate.appPackageName,
        fileType: 1,
      };

      const cb = (res) => {
        if (this.source === "appUpload") {
          this.$emit("confirm", res);
        } else {
          this.$emit("update:model-value", false);
          this.$router.push({
            path: `/flyparameter/config/${res.id}`,
            query: {
              unsaved: true,
            },
          });
        }
      };
      if (this.isBlankTemplate) {
        createBlankTemplate(data)
          .then(cb)
          .catch(this.$confirmError)
          .finally(() => {
            this.loading = false;
          });
      } else {
        createTemplateByTemplateId(data, this.commonTemplateId)
          .then((res) => {
            this.loadingDialogVisible = true;
            this.loadingDialogTitle = "Loading template";
            this.appPackageName = res.appPackageName;
            this.estimateTime = res.estimateTime;
            this.taskUuid = res.taskUuid;
            this.$emit("update:model-value", false);
            // cb()
          })
          .catch(this.$confirmError)
          .finally(() => {
            this.loading = false;
          });
      }
    },
    fetchTemplates() {
      this.loading = true;
      getSpecificModeTemplateList(this.mode)
        .then((res) => {
          this.templates = [...res];
        })
        .finally(() => {
          this.loading = false;
        });
    },
    editTemplate(id) {
      this.$emit("update:model-value", false);
      if (this.source === "appUpload") {
        this.$store.commit("app/ADD_KEEP_ALIVE_LIST", "ApplicationUpload");
      } else {
        this.$store.commit("app/ADD_KEEP_ALIVE_LIST", "FlyParameter");
      }
      this.keepAlive = true;
      this.$nextTick(() => {
        this.$router.push(`/flyparameter/config/${id}?from=${this.$route.path}`);
      });
    },

    deleteTemplate(app) {
      this.$commonConfirm({
        title: this.$t("flyparam.delete_template"),
        type: "danger",
        modal: false,
        content: this.$t("flyparam.delete_template_warning", {
          id: app.appName,
        }),
        btnSureTitle: this.$t("common.delete"),
        onConfirm: async (instance, done) => {
          instance.loading = true;
          try {
            await deleteTemplateByTemplateId(app.id);
            this.$message.success(this.$t("flyparam.delete_success"));
          } catch (e) {
            this.$confirmError(e).then(() => {
              done();
            });
          }
          done();
          this.fetchTemplates();
        },
      });
    },

    handleFileChange(file) {
      this.formData = new FormData();
      this.formData.append("file", file.raw);
      request({
        url: `/online/management/fly-parameter/template/design/import/whole`,
        method: "POST",
        params: {
          appName: this.info.appName,
          appPackageName: this.info.appPackageName,
          mode: this.mode,
        },
        data: this.formData,
      })
        .then((res) => {
          this.fileName = file.name;
          this.appPackageName = res.appPackageName;
          this.loadingDialogVisible = true;
          this.loadingDialogTitle = "Importing template";
          this.taskUuid = res.taskUuid;
          this.estimateTime = res.estimateTime;
          // this.$progressInterval = setInterval(() => {
          //   if(this.progress >= 100) {
          //     clearInterval(this.$progressInterval)
          //     return
          //   }
          //   this.progress += 5
          // }, 2000)
          // this.$requestInterval = setInterval(() => {
          //   getTaskProgress(res.taskUuid).then(res => {
          //     if(res.status === 1) {
          //       this.$message.success('Imported Successfully.')
          //       clearInterval(this.$requestInterval)
          //       this.progress = 100
          //       return
          //     }
          //   })
          // }, 5000)

          // this.$refs.upload.clearFiles()
          // this.showUpload = true
          // this.percentState = 0
        })
        .catch((err) => {
          this.$message.error(err.message);
          this.$refs.upload.clearFiles();
          this.percentState = 0;
        });
    },

    open() {
      this.fetchTemplates();
    },
    changeMode(mode, className) {
      if (mode !== this.mode) {
        this.selectedTemplateIndex = "blank";
        this.active = className;
        this.mode = mode;
        this.fetchTemplates();
      }
    },
    // 关闭嵌套的新建模板对话框
    newTemplateClose() {
      if (this.visible) {
        this.$refs.form.resetFields();
        this.visible = false;
      }
    },
    newTemplate() {
      this.loading = true;
      this.$refs["form"].validate((valid) => {
        if (valid) {
          addCommonParamTemplate(this.mode, { ...this.form })
            .then((res) => {
              this.newTemplateClose();
              this.keepAlive = true;
              this.$emit("update:model-value", false);
              if (this.source === "appUpload") {
                this.$store.commit("app/ADD_KEEP_ALIVE_LIST", "ApplicationUpload");
              } else {
                this.$store.commit("app/ADD_KEEP_ALIVE_LIST", "FlyParameter");
              }
              this.$nextTick(() => {
                this.$router.push({
                  path: `/flyparameter/config/${res.id}`,
                  query: {
                    from: this.$route.path,
                    unsaved: true,
                  },
                });
              });
            })
            .catch(this.$confirmError)
            .finally(() => {
              this.loading = false;
            });
        } else {
          this.loading = false;
          return false;
        }
      });
    },
  },
  activated() {
    this.$emit("update:model-value", true);
    this.fetchTemplates();
    this.keepAlive = false;
  },
};
</script>

<style lang="scss" scoped>
$activeColor: #409eff;

.progress {
  margin: 10px;
  width: 700px;
  height: 20px;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 20px;
  overflow: hidden;
  background-color: #f5f5f5;
  border-radius: 4px;
  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
  .progress-bar {
    background-image: linear-gradient(
      45deg,
      rgba(255, 255, 255, 0.15) 25%,
      transparent 25%,
      transparent 50%,
      rgba(255, 255, 255, 0.15) 50%,
      rgba(255, 255, 255, 0.15) 75%,
      transparent 75%,
      transparent
    );
    -webkit-background-size: 40px 40px;
    background-size: 40px 40px;
    animation: progress-bar-stripes 2s linear infinite;
    float: left;
    width: 0;
    height: 100%;
    font-size: 12px;
    line-height: 20px;
    color: #fff;
    text-align: center;
    background-color: #337ab7;
    -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
    -webkit-transition: width 0.6s ease;
    -o-transition: width 0.6s ease;
    transition: width 0.6s ease;

    &--success {
      background-color: #5cb85c;
    }

    @keyframes progress-bar-stripes {
      0% {
        background-position: 40px 0;
      }

      100% {
        background-position: 0 0;
      }
    }
  }
}
.select-template-dialog {
  &::v-deep {
    .el-dialog__body {
      padding: 0;
    }
  }

  .sidebar {
    border-right: 1px solid #e5effb;

    .title {
      border-bottom: 1px solid #e5effb;
    }

    .menu {
      padding: 10px 12px;
    }

    .menu-item {
      cursor: pointer;
      // height: 125px;
      line-height: 40px;
      text-align: center;
      border-radius: 4px;
      // padding: 10px 16px;

      img {
        border: 2px solid transparent;
        border-radius: 4px;
      }

      &:last-child {
        margin-top: 30px;
      }

      // border-bottom: 1px solid #e5effb;
      // border-left: 4px solid transparent;
      &:hover {
        color: rgb(45, 130, 239);
        img {
          border-color: $activeColor;
        }
      }

      &.active {
        // border-left-color: $activeColor;
        // color: $activeColor;
        font-weight: bold;
        color: rgb(45, 130, 239);
        // background-color: rgb(242, 248, 255);
        img {
          border-color: $activeColor;
        }
      }
    }
  }

  .select-template {
    border-right: 1px solid #e5effb;
    position: relative;

    .title {
      padding: 10px 0;
      color: #767676;
    }

    .templates-container {
      padding: 0 10px 20px;
      min-height: 300px;
      margin-bottom: 90px;
    }

    .select-template__footer {
      width: 100%;
      // position: absolute;
      z-index: 3;
      bottom: 0;
      position: absolute;
      padding: 22px 30px;
      background: #ffffff;
      text-align: right;
      border-top: 1px solid #e5effb;
    }

    .template-box {
      cursor: pointer;
      text-align: center;
      margin-right: 10px;
      border: 2px solid #dcdfe6;
      border-radius: 4px;
      display: inline-block;
      position: relative;
      width: 100%;
      height: 180px;

      .image-tag {
        z-index: 2;
        position: relative;
        font-size: 12px;
        bottom: -105px;
        /* display: block; */
        background: #bcd9ea;
        padding: 0px 10px;
        border-radius: 4px;
        color: #172b4d;
        width: 60%;
        margin: 0 auto;
        font-weight: bold;
        display: inline;
      }

      &:not(.blank):hover {
        .template-actions {
          opacity: 1;
        }

        .template-box__bottom .template-name {
          opacity: 0;
        }
      }

      .template-box__bottom {
        text-align: left;
        position: absolute;
        bottom: 0;
        width: 100%;
        padding: 10px;
        border-top: 2px solid #dcdfe6;

        .template-name {
          transition: opacity 0.2s;
          opacity: 1;
          text-align: center;
        }
      }

      .template-image {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 79%;
      }

      .item-new {
        position: absolute;
        top: 50%;
        left: 50%;
        font-size: 36px;
        transform: translate(-50%, -50%);
      }

      //padding: 65px 120px;
      &.new {
        border-style: dashed;

        &:hover {
          color: $activeColor;
        }
      }
      // 空白模板
      &.blank {
        &:hover {
          color: $activeColor;
        }
      }

      &:hover {
        border-color: $activeColor;

        & + p {
          color: $activeColor;
        }
      }

      &.selected {
        border-color: $activeColor;
        border-width: 2px;

        & + p {
          color: $activeColor;
        }
      }

      .template-actions {
        transition: opacity 0.2s;
        opacity: 0;
        width: 100%;
        bottom: 10px;
        text-align: center;
        position: absolute;
        padding-right: 15px;

        span {
          i {
            transition: all 0.3s;
          }

          &:hover {
            color: $activeColor;

            i {
              transform: scale(1.2);
            }
          }
        }
      }

      /*.template-actions {
        position: absolute;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        text-align: center;
        color: #fff;
        opacity: 0;
        font-size: 20px;
        background-color: rgba(0, 0, 0, 0.5);
        transition: opacity 0.3s;
        &:hover {
          opacity: 1;
        }
        .item-delete,
        .item-edit,
        .item-new {
          &:hover {
            color: $activeColor;
          }
        }
      }*/
    }

    .import-template {
      padding: 0 10px 30px;
    }
  }

  .introduction {
    padding: 10px;
    height: calc(100vh - 90px);
    overflow: auto;

    ul {
      list-style: disc;
      padding-left: 40px;
    }
  }
}

.select-file-format::v-deep .el-dialog__body {
  padding: 30px 20px;
}

.select-template-dialog::v-deep {
  .el-upload {
    width: 100%;
  }
  .el-upload-dragger {
    width: 100%;
    height: 180px;

    .el-icon-upload {
      line-height: 50px;
    }
  }
}

.progress-bar .choose-format {
  padding: 50px;
}
</style>
